package cn.tedu.charging.cost.service.impl;

import cn.tedu.charging.common.pojo.param.ProgressCostParam;
import cn.tedu.charging.common.pojo.vo.ProgressCostVO;
import cn.tedu.charging.cost.dao.repository.CostRuleRepository;
import cn.tedu.charging.cost.pojo.po.ChargingCostRulePO;
import cn.tedu.charging.cost.service.CostService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Service
@Slf4j
public class CostServiceImpl implements CostService {

    @Autowired
    private CostRuleRepository costRuleRepository;
    @Override
    public ProgressCostVO calculateCost(ProgressCostParam param) {
        //1.拿到当前系统时间 获得一个小时数 当前时间如果是8:55 小时数就是8
        Integer hour=getCurentHour();
        //2.利用场站id 和枪类型 以及hour时间 查询持久化CostRulePO
        ChargingCostRulePO rule=getCostRule(param.getStationId(),hour);
        //3.利用当前的参数,以及rule中单价,计算单次充电度数,以及总金额
        ProgressCostVO vo=new ProgressCostVO();
        vo.setPowerFee(rule.getPowerFee().doubleValue());
        calculateCapacityAndTotalCost(param,rule,vo);
        return vo;

    }

    private void calculateCapacityAndTotalCost(ProgressCostParam param, ChargingCostRulePO rule, ProgressCostVO vo) {
  /*
        入参 有总度数 totalCapacity
        想要计算 单次充电度数,可以利用存储上次充电总数和当前总度数做一个差计算
        currentTotalCapacity-lastTotalCapacity=单次度数
        本次充电的金额
        单次度数*powerFee=currentCost
        totalCost计算 可以利用上次的总金额和本次单次金额累加
        currentCost+lastTotalCost=totalCost
        */
        //1.读取上次总度数 底层使用redis存储 设置最大超时时间2天 key值设计和订单订单
        BigDecimal lastTotalCapacity=costRuleRepository.getAndSetTotalCapaicity(param.getOrderNo(),param.getTotalCapacity());
        BigDecimal currentCapacity=null;//准备好计算的本次充电度数
        if (lastTotalCapacity==null){
            currentCapacity=new BigDecimal(param.getTotalCapacity()+"");
        }else{
            //2.利用本次总度数,减去上次总度数
            currentCapacity=new BigDecimal(param.getTotalCapacity()+"").subtract(lastTotalCapacity);
        }
        //3.利用本次充电度数 和单价做相乘 得到本次充电金额
        BigDecimal currentCost=currentCapacity.multiply(rule.getPowerFee());
        //4.累加 存储本次单价和上次的总价 利用redis存储该订单的总金额,做累加
        BigDecimal totalCost=costRuleRepository.accumulateTotalCost(param.getOrderNo(),currentCost);
        vo.setTotalCost(totalCost.doubleValue());
        vo.setChargingCapacity(currentCapacity.doubleValue());
    }

    private ChargingCostRulePO getCostRule(Integer stationId, Integer hour) {
        //从数据层获取 返回使用
        return costRuleRepository.getCostRule(stationId,hour);
    }

    private Integer getCurentHour() {
        return LocalDateTime.now().getHour();
    }
}
